package com.jfinal.weixin.api;

import com.alibaba.fastjson.JSON;
import com.jfinal.utils.MediaFile;
import com.jfinal.utils.http.HttpUtil;
import com.jfinal.weixin.api.model.MediaArticle;
import com.jfinal.weixin.common.MediaType;

import java.io.File;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 素材管理 api
 * 新增,获取临时素材
 * 新增,获取,删除永久素材,获取永久素材总数,列表
 * 多媒体文件有格式和大小限制
 *    图片（image）: 1M，支持JPG格式
 *    语音（voice）：2M，播放长度不超过60s，支持AMR\MP3格式
 *    视频（video）：10MB，支持MP4格式
 *    缩略图（thumb）：64KB，支持JPG格式
 * Created by shitiangao on 16/5/20.
 */
public enum MaterialApi {
    ice;
    
    /**
     * 上传临时素材
     * 1、对于临时素材，每个素材（media_id）会在开发者上传或粉丝发送到微信服务器3天后自动删除
     *    （所以用户发送给开发者的素材，若开发者需要，应尽快下载到本地），以节省服务器资源。
     * 2、media_id是可复用的。
     * 3、素材的格式大小等要求与公众平台官网一致。具体是，图片大小不超过2M，支持bmp/png/jpeg/jpg/gif格式，
     *     语音大小不超过5M，长度不超过60秒，支持mp3/wma/wav/amr格式
     * 4、需使用https调用。
     * @param accessToken
     * @param mediaType 上传的临时多媒体文件格式
     * @param file 需要上传的文件
     * @return ApiResult
     */
    public ApiResult uploadTempMedia(String accessToken, MediaType mediaType, File file) {
        String url = APIConfig.WX__MEDIA_UPLOAD_TEMP;
        url = url.replace("ACCESS_TOKEN", accessToken).replace("TYPE", mediaType.toString());

        return ApiResult.create(HttpUtil.upload(url, file, ""));
    }

    /**
     * 获取临时素材
     * @param mediaId 素材Id
     * @return MediaFile
     */
    public MediaFile getTempMedia(String accessToken, String mediaId) {
        String url = APIConfig.WX__MEDIA_DOWNLOAD_TEMP;
        url = url.replace("ACCESS_TOKEN", accessToken).replace("MEDIA_ID", mediaId);

        return HttpUtil.download(url);
    }

    /**
     * 新增永久素材
     * 永久图片素材新增后，将带有URL返回给开发者，
     * 开发者可以在腾讯系域名内使用（腾讯系域名外使用，图片将被屏蔽）
     * @param accessToken
     * @param list 图文信息列表
     * @return
     */
    public ApiResult addMaterialNews(String accessToken, List<MediaArticle> list) {
        String url = APIConfig.WX__MATERAL_NEWS_ADD;
        url = url.replace("ACCESS_TOKEN", accessToken);

        Map<String, List<MediaArticle>> postData = new HashMap<>();
        postData.put("articles", list);

        return ApiResult.create(HttpUtil.post(url, JSON.toJSONString(postData)));
    }

    /**
     * 修改永久图文素材
     * 也可以更新在公众平台官网素材管理模块中保存的图文消息（永久图文素材）
     * @param accessToken
     * @param mediaId 要修改的图文消息的id
     * @param index 要更新的文章在图文消息中的位置（多图文消息时，此字段才有意义），第一篇为0
     * @param article 图文消息对象
     * @return
     */
    public ApiResult updateMaterialNews(String accessToken, String mediaId,
                                Integer index, MediaArticle article) {
        String url = APIConfig.WX__MATERAL_NEWS_UPDATE;
        url = url.replace("ACCESS_TOKEN", accessToken);

        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("media_id", mediaId);
        dataMap.put("index", index);
        dataMap.put("articles", article);

        return ApiResult.create(HttpUtil.post(url, JSON.toJSONString(dataMap)));
    }


    /**
     * 上传图文消息内的图片获取URL
     * 本接口所上传的图片不占用公众号的素材库中图片数量的5000个的限制。
     * 图片仅支持jpg/png格式，大小必须在1MB以下。
     * @param accessToken
     * @param file
     * @return
     */
    public ApiResult uploadMaterialImg(String accessToken, File file) {
        String url = APIConfig.WX__MATERAL_IMG_UPLOAD;
        url = url.replace("ACCESS_TOKEN", accessToken);

        return ApiResult.create(HttpUtil.upload(url, file, ""));
    }

    /**
     * 新增其他类型永久素材
     * 通过POST表单来调用接口，表单id为media，
     * 包含需要上传的素材内容，有filename、filelength、content-type等信息。
     * 注意：图片素材将进入公众平台官网素材管理模块中的默认分组。
     * @param accessToken
     * @param mediaType 媒体文件类型,MediaType 图片（image）、语音（voice）、视频（video）和缩略图（thumb）
     * @param file
     * @return
     */
    public ApiResult uploadMaterial(String accessToken, MediaType mediaType, File file) {
        String url = APIConfig.WX__MATERAL_UPLOAD;
        url = url.replace("ACCESS_TOKEN", accessToken).replace("TYPE", mediaType.toString());

        return ApiResult.create(HttpUtil.upload(url, file, ""));
    }

    /**
     * 新增视频类型永久素材
     * 在上传视频素材时需要POST另一个表单，id为description，包含素材的描述信息
     * @param accessToken
     * @param file
     * @param title 视频素材的标题
     * @param introduction 视频素材的描述
     * @return
     */
    public ApiResult addMaterialVideo(String accessToken, File file, String title, String introduction) {
        String url = APIConfig.WX__MATERAL_UPLOAD;
        url = url.replace("ACCESS_TOKEN", accessToken).replace("TYPE", "video");

        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("title", title);
        dataMap.put("introduction", introduction);

        return ApiResult.create(HttpUtil.upload(url, file, JSON.toJSONString(dataMap)));
    }

    /**
     * 获取永久素材
     * 1、获取永久素材也可以获取公众号在公众平台官网素材管理模块中新建的图文消息、图片、语音、视频等素材
     *      （但需要先通过获取素材列表来获知素材的media_id）
     * 2、临时素材无法通过本接口获取
     * 3、调用该接口需https协议
     * @param accessToken
     * @param mediaId
     * @return
     *  微信此接口有三种返回,
     *  图文消息返回详细内容,视频消息返回属性和下载地址,此两种为 json 消息
     *  其他类型素材返回的是文件
     */
    public InputStream getMaterial(String accessToken, String mediaId) {
        String url = APIConfig.WX__MATERAL_GET;
        url = url.replace("ACCESS_TOKEN", accessToken);

        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("media_id", mediaId);

        return HttpUtil.download(url, JSON.toJSONString(dataMap));
    }

    /**
     * 删除永久素材
     * 请谨慎操作本接口，因为它可以删除公众号在公众平台官网素材管理模块中新建的图文消息、语音、视频等素材
     * （但需要先通过获取素材列表来获知素材的media_id）
     * @param accessToken
     * @param mediaId 要删除的图文消息的id
     * @return
     */
    public ApiResult delMaterial(String accessToken, String mediaId) {
        String url = APIConfig.WX__MATERAL_DEL;
        url = url.replace("ACCESS_TOKEN", accessToken);

        Map<String, String> dataMap = new HashMap<String, String>();
        dataMap.put("media_id", mediaId);

        return ApiResult.create(HttpUtil.post(url, JSON.toJSONString(dataMap)));
    }


    /**
     * 获取素材总数
     * 1.永久素材的总数，也会计算公众平台官网素材管理中的素材
     * 2.图片和图文消息素材（包括单图文和多图文）的总数上限为5000，其他素材的总数上限为1000
     * @param accessToken
     * @return
     */
    public ApiResult getMaterialCount(String accessToken) {
        String url = APIConfig.WX__MATERAL_COUNT_GET;
        url = url.replace("ACCESS_TOKEN", accessToken);

        return ApiResult.create(HttpUtil.post(url));
    }

    /**
     * 获取素材列表
     * 在新增了永久素材后，开发者可以分类型获取永久素材的列表。
     * @param type 素材的类型 MediaType
     * @param offset 从全部素材的该偏移位置开始返回，0表示从第一个素材 返回
     * @param count 返回素材的数量，取值在1到20之间
     * @return
     */
    public ApiResult getMaterialBatch(String accessToken, MediaType type,
                                      Integer offset, Integer count) {
        String url = APIConfig.WX__MATERAL_BATCH_GET;
        url = url.replace("ACCESS_TOKEN", accessToken);

        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("type", type.toString());
        dataMap.put("offset", offset);
        dataMap.put("count", count);

        return ApiResult.create(HttpUtil.post(url, JSON.toJSONString(dataMap)));
    }
}
